Справочник по языку Groovy
Назначение
Справочник-шпаргалка по Groovy: типы, синтаксис, стандартная библиотека, типовые паттерны. Не заменяет пошаговое обучение. Учебный курс: [раздел](/encyclopedia/5-languages/5.12. Groovy/intro).
Краткое пояснение
Компоненты и ключевые особенности языка.
Быстрый старт
groovy hello.groovy Alice
Справочные таблицы
Содержание справочника
- 1. Типы данных
- 2. Операторы
- 3. Управляющие конструкции
- 4. Методы и функции
- 5. Классы и объекты
- 6. Замыкания (Closures)
- 7. Коллекции и их методы
- 8. Метапрограммирование
- 9. Компиляция и настройки
- 10. Интеграция с Java
- 11. DSL и скриптование
- 12. Распространённые утилиты и расширения
- 13. Безопасность и ограничения
- 14. AST-трансформации (Compile-time Metaprogramming)
- 15. Расширенное метапрограммирование
- 16. Работа с данными
- 17. Шаблоны
- 18. Интеграция с Gradle
- 19. Тестирование: Spock Framework
- 20. Производительность и оптимизация
- 21. Практическое применение Groovy
- 22. Версии и совместимость
- 23. Ограничения и предостережения
- 24. Встроенные методы расширений (GDK — Groovy Разработка Kit)
- 25. Регулярные выражения
- 26. Многопоточность и параллелизм
- 27. Управление ресурсами и замыкания
- 28. Практические паттерны использования
- 29. Инструменты и экосистема
- 30. Советы по стилю и читаемости
- 31. Структура типичного Groovy-проекта
- 32. Организация кода
- 33. Управление зависимостями
- 34. Конфигурация приложения
- 35. Настройка компилятора Groovy
- 36. Обработка ошибок и логирование
- 37. Тестирование и проверка качества
- 38. Запуск и развёртывание
- 39. Безопасность при выполнении скриптов
- 40. Профилирование и отладка
- 41. Обновление и миграция
- 42. Когда использовать Groovy — и когда нет
1. Типы данных
Простые типы
null— отсутствие значения.boolean— логическое значение:true,false.char— одиночный символ в одинарных кавычках:'A'.int,long,BigInteger— целочисленные типы.float,double,BigDecimal— числа с плавающей точкой.
Строки
- GString (
"...") — интерполируемая строка, поддерживает выражения${выражение}. - String (
'...') — обычная строка без интерполяции. - Triple-quoted string (
'''...''') — многострочная строка без интерполяции. - Slashy string (
/.../) — удобна для регулярных выражений, не требует экранирования слешей. - Dollar-slashy string (
$/.../$) — многострочная строка с интерполяцией и минимальным экранированием.
Коллекции
- List — упорядоченный список, изменяемый по умолчанию:
def list = [1, 2, 3]
- Set — множество уникальных элементов:
def set = [1, 2, 3] as Set
- Map — ассоциативный массив:
def map = [name: 'Alice', age: 30]
Диапазоны (Ranges)
- Используются для перебора значений:
def range = 1..5 // включительноdef exclusive = 1..<5 // исключительно
Файлы и ресурсы
- Объект
Fileиспользуется напрямую из Java. - Groovy добавляет методы вроде
eachLine,splitEachLine,withReader.
2. Операторы
Арифметические
+,-,*,/,%,**(возведение в степень)
Логические
&&,||,!
Побитовые
&,|,^,~,<<,>>,>>>
Операторы сравнения
==,!=,<,<=,>,>=- Groovy переопределяет
==как вызов.equals(), а не сравнение ссылок.
Операторы присваивания
=,+=,-=,*=,/=,%=,**=,&=,|=,^=,<<=,>>=,>>>=
Операторы безопасной навигации
?.— вызов метода или доступ к свойству только если объект не null:person?.address?.city
Оператор Elvis
?:— возвращает левый операнд, если он не null и не false; иначе — правый:name = providedName ?: 'Anonymous'
Оператор распространения (Spread operator)
*.— применяет метод ко всем элементам коллекции:names*.toUpperCase()
Оператор объединения списков
+— объединяет списки или карты.-— удаляет элементы из списка или ключи из карты.
Оператор индексации
[]— доступ к элементу по индексу или ключу:list[0], map['key'], map.key
Оператор диапазона
..,..<
Оператор замыкания
{ параметры -> тело }
3. Управляющие конструкции
Условные операторы
if / else if / elseswitch / case— поддерживает сопоставление с любыми типами, включая классы, регулярные выражения, замыкания.
Циклы
for (i in collection)— итерация по коллекции, диапазону, массиву.while (condition) { ... }loop.each { item -> ... }— функциональный стиль через замыкания.
Обработка исключений
try / catch / finally— стандартный механизм Java, полностью поддерживается.
4. Методы и функции
Объявление
- Методы объявляются с помощью ключевого слова
defили явного типа возврата:def greet(name) { "Hello, $name!" }String greet(String name) { "Hello, $name!" }
Необязательные параметры
- Поддерживаются значения по умолчанию:
def log(message, level = 'INFO') { ... }
Переменное число аргументов
- Используется оператор
...:def sum(int... numbers) { numbers.sum() }
Явный возврат
- Последнее выражение в методе автоматически возвращается, но можно использовать
return.
5. Классы и объекты
Объявление класса
class Person {
String name
int age
String toString() { "$name ($age)" }
}
Автоматические геттеры и сеттеры
- Все поля получают геттеры и сеттеры по соглашению.
Конструкторы
- Конструктор по умолчанию принимает
Map:def p = new Person(name: 'Bob', age: 25)
Наследование
- Поддерживается через
extends.
Интерфейсы и трейты
- Интерфейсы работают как в Java.
- Traits — мощный механизм повторного использования кода:
trait Flyable { void fly() { println "Flying!" } }class Bird implements Flyable { }
Аннотации
- Поддерживаются все Java-аннотации.
- Groovy предоставляет собственные аннотации:
@CompileStatic,@TypeChecked,@Delegate,@Lazy,@Immutable,@Sortable,@Canonical, и другие.
6. Замыкания (Closures)
Синтаксис
{ param1, param2 -> body }
Неявные параметры
it— имя по умолчанию для единственного параметра:[1, 2, 3].each { println it }
Делегирование
- Замыкание может иметь
delegate, который определяет контекст выполнения:closure.delegate = someObjectclosure.resolveStrategy = Closure.DELEGATE_FIRST
Полезные методы для замыканий
call(),curry(),rcurry(),memoize(),trampoline()
7. Коллекции и их методы
List
size(),isEmpty(),get(index),putAt(index, value)each,collect,findAll,any,every,groupBy,sort,reverse,unique,flatten,sum,min,max
Map
keySet(),values(),entrySet()each,collectEntries,findAll,any,every,groupBy,subMap
String
eachMatch(regex),tokenize(),padLeft(),padRight(),toInteger(),toDouble(),replaceAll(),eachLine()
8. Метапрограммирование
Runtime metaprogramming
- Добавление методов и свойств во время выполнения:
Person.metaClass.greet = { -> "Hi from $name" }
ExpandoMetaClass
- Включается глобально или для конкретного класса.
methodMissing / propertyMissing
- Перехват вызовов несуществующих методов или свойств.
invokeMethod
- Перехват всех вызовов методов объекта.
Categories
- Временное расширение поведения классов в блоке
use.
AST Transformations (compile-time)
- Изменяют дерево абстрактного синтаксиса на этапе компиляции.
- Примеры:
@ToString,@EqualsAndHashCode,@TupleConstructor,@Bindable,@ListenerList
9. Компиляция и настройки
Режимы компиляции
- Dynamic — поведение по умолчанию, проверка типов во время выполнения.
- Static compilation — через
@CompileStatic, обеспечивает производительность как у Java. - Type checking — через
@TypeChecked, проверяет типы, но оставляет динамическое поведение.
Параметры компилятора Groovy
indy— использование invokedynamic (JDK 7+).encoding— кодировка исходного файла.targetBytecode— версия байткода (например,1.8,11,17).parameters— сохранение имён параметров в байткоде.previewFeatures— включение preview-функций JDK.
Конфигурация через groovyOptions
В Gradle:
compileGroovy {
groovyOptions.optimizationOptions.indy = true
groovyOptions.configurationScript = file('config.groovy')
}
10. Интеграция с Java
- Любой Java-класс доступен напрямую.
- Groovy-классы компилируются в байткод JVM и могут использоваться из Java.
- Совместимость с Java Collections API, Streams, Optional и другими конструкциями.
11. DSL и скриптование
GroovyShell
- Выполнение строк как кода:
new GroovyShell().evaluate('2 + 3')
GroovyScriptEngine
- Загрузка и выполнение скриптов из файлов.
Builder-паттерн
- Встроенные
MarkupBuilder,JsonBuilder,StreamingJsonBuilder,ObjectGraphBuilder.
Пример:
def builder = new MarkupBuilder()
builder.person {
name 'Alice'
age 30
}
12. Распространённые утилиты и расширения
Расширения для чисел
times { ... }— повторить действие N раз.upto(to) { ... },downto(to) { ... }
Расширения для файлов
eachFile,eachDir,deleteDir(),getText(),write(text)
Расширения для потоков
withStream { ... },withWriter { ... }
Расширения для дат
Date.plus(days),Date.minus(days),parse(format, string)
13. Безопасность и ограничения
- При выполнении внешних скриптов используйте
SecureASTCustomizerдля ограничения доступа к опасным API. - Отключите возможность создания новых классов, вызова
System.exit, доступа к файловой системе и т.п.
Пример:
def secure = new SecureASTCustomizer()
secure.closuresAllowed = false
secure.methodDefinitionAllowed = false
14. AST-трансформации (Compile-time Metaprogramming)
Groovy позволяет изменять структуру кода на этапе компиляции через аннотации, которые преобразуют абстрактное синтаксическое дерево (AST). Это мощный механизм для генерации кода без рантайм-накладных расходов.
Встроенные AST-трансформации
@Canonical
Объединяет @ToString, @EqualsAndHashCode, @TupleConstructor:
@Canonical
class Person {
String name
int age
}
@ToString
Генерирует метод toString():
@ToString(includeNames = true, includePackage = false)
class Point { int x, y }
// Результат: Point(x:10, y:20)
Параметры:
includeNames— добавлять имена полей.includePackage— включать имя пакета.excludes— исключить поля.includes— включить только указанные поля.
@EqualsAndHashCode
Генерирует equals() и hashCode().
@TupleConstructor
Создаёт конструктор на основе полей:
@TupleConstructor
class Point { int x, y }
def p = new Point(1, 2)
@Immutable
Делает класс неизменяемым:
- Все поля становятся
final. - Генерируются геттеры.
- Коллекции оборачиваются в неизменяемые обёртки.
- Класс объявляется
final.
@Sortable
Добавляет реализацию Comparable и статические методы comparatorBy*.
@Delegate
Делегирует вызовы методов другому объекту:
class Engine {
void start() { println "Engine started" }
}
class Car {
@Delegate Engine engine = new Engine()
}
new Car().start() // вызывает engine.start()
@Lazy
Ленивая инициализация поля:
class Heavy {
@Lazy def resource = { /* expensive init */ }()
}
@Synchronized
Автоматически оборачивает метод в synchronized.
@Field
Превращает переменную в поле класса (в скриптах):
@Field String name = 'Alice'
@PackageScope
Делает член класса доступным только в пределах пакета.
@Bindable и @Vetoable
Используются в GUI-приложениях для поддержки property change listeners.
15. Расширенное метапрограммирование
ExpandoMetaClass
Позволяет динамически добавлять методы, свойства, статические методы:
String.metaClass.shout = { -> delegate.toUpperCase() + '!' }
println "hello".shout() // HELLO!
Включение глобально:
ExpandoMetaClass.enableGlobally()
methodMissing и propertyMissing
Перехват несуществующих вызовов:
class Dynamic {
def methodMissing(String name, args) {
return "Called $name with ${args.join(', ')}"
}
}
invokeMethod
Перехват всех вызовов методов (включая существующие, если metaClass.invokeMethod переопределён).
getProperty / setProperty
Контроль доступа к свойствам.
Categories
Временное расширение поведения:
class NumberUtils {
static double square(Number n) { n * n }
}
use(NumberUtils) {
println 5.square() // 25.0
}
16. Работа с данными
JSON
Чтение
def json = new JsonSlurper().parseText('{"name":"Alice"}')
println json.name
Запись
def builder = new JsonBuilder()
builder.person {
name 'Alice'
age 30
}
println builder.toPrettyString()
StreamingJsonBuilder
Для больших объёмов данных:
def writer = new StringWriter()
def builder = new StreamingJsonBuilder(writer)
builder.people {
person { name 'Alice' }
}
XML
Parsing
def xml = '''
<books>
<book title="Groovy Guide"/>
</books>
'''
def Данные = new XmlSlurper().parseText(xml)
println Данные.book[0].@title
Построение
def builder = new MarkupBuilder()
builder.books {
book(title: 'Groovy Guide')
}
XPath-подобные запросы
Данные.book.findAll { it.@year.toInteger() > 2020 }
17. Шаблоны
SimpleTemplateEngine
Поддерживает ${выражения}:
def engine = new SimpleTemplateEngine()
def template = engine.createTemplate('Hello, $name!')
def result = template.make(name: 'Alice')
GStringTemplateEngine
Более мощный, поддерживает логику внутри шаблона.
XmlTemplateEngine
Для генерации XML с логикой.
18. Интеграция с Gradle
Groovy — основной язык написания скриптов сборки в Gradle (до появления Kotlin DSL).
Пример build.gradle:
plugins {
id 'groovy'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.codehaus.groovy:groovy-all:4.0.15'
testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
}
Кастомные задачи на Groovy
task hello {
doLast {
println "Hello from Groovy in Gradle!"
}
}
Конфигурация компилятора
compileGroovy {
groovyOptions.optimizationOptions.indy = true
groovyOptions.targetBytecode = '17'
}
19. Тестирование: Spock Framework
Spock — BDD-фреймворк на Groovy, сочетающий выразительность и мощь.
Структура спецификации
class MathSpec extends Specification {
def "sum of two numbers"() {
expect:
a + b == c
where:
a | b || c
1 | 2 || 3
4 | 5 || 9
}
}
Блоки
given— подготовкаwhen— действиеthen— проверкаexpect— комбинация when/thenwhere— параметризацияcleanup— завершениеsetup— аналог@Before
Моки и спайки
def service = Mock(Service)
service.process(_) >> "OK"
20. Производительность и оптимизация
Статическая компиляция
Используйте @CompileStatic для критичных к производительности участков:
@CompileStatic
int factorial(int n) {
n <= 1 ? 1 : n * factorial(n - 1)
}
Избегайте динамических вызовов в циклах
Кэшируйте методы или используйте интерфейсы.
Используйте @TypeChecked для поиска ошибок
Проверяет типы, но сохраняет динамические возможности при необходимости.
invokedynamic (indy)
Включите флаг -indy при компиляции для ускорения вызовов замыканий и динамических методов (требует JDK 7+).
Профилирование
Используйте VisualVM, JProfiler или async-profiler для анализа узких мест.
21. Практическое применение Groovy
Скрипты автоматизации
- Обработка логов
- Генерация конфигураций
- Миграции данных
DSL для конфигурации
server {
port 8080
host 'localhost'
ssl enabled: true
}
Jenkins Pipelines
Declarative и Scripted Pipelines на Groovy.
Тестовые фреймворки
- Spock
- Geb (для UI-тестов)
Встраивание в Java-приложения
- Через
GroovyShell - Через
GroovyScriptEngineдля горячей замены логики
22. Версии и совместимость
- Groovy 2.x — поддержка JDK 6–8, начало AST-трансформаций.
- Groovy 3.x — поддержка Java 8+, новые операторы (
!in,!instanceof), улучшенная совместимость с Java. - Groovy 4.x — поддержка JDK 17, улучшенная статическая компиляция, модульность, Jakarta EE.
Рекомендуется использовать Groovy 4.0+ для новых проектов.
23. Ограничения и предостережения
- Динамическая природа снижает производительность по сравнению с Java.
- Отладка динамического кода сложнее.
- Некоторые IDE хуже поддерживают Groovy, чем Java.
- При смешивании с Java возможны неочевидные ошибки из-за различий в семантике
==,in,[].
24. Встроенные методы расширений (GDK — Groovy Разработка Kit)
Groovy автоматически добавляет сотни полезных методов к стандартным классам Java через механизм метаклассов. Эти методы определены в классах:
DefaultGroovyMethods— для большинства объектовDefaultGroovyStaticMethods— статические методыStringGroovyMethods,FileGroovyMethods,IOGroovyMethods,SqlGroovyMethodsи др.
Эти методы доступны везде, без импорта.
Общие методы для коллекций
each
[1, 2, 3].each { println it }
collect
Преобразует каждый элемент:
[1, 2, 3].collect { it * 2 } // [2, 4, 6]
findAll / grep
Фильтрация:
[1, 2, 3, 4].findAll { it % 2 == 0 } // [2, 4]
['a1', 'b2', 'c3'].grep(~/\d$/) // строки, оканчивающиеся цифрой
any / every
Проверка условий:
[1, 2, 3].any { it > 2 } // true
[1, 2, 3].every { it > 0 } // true
groupBy
Группировка:
['apple', 'banana', 'cherry'].groupBy { it[0] }
// [a:['apple'], b:['banana'], c:['cherry']]
sum, min, max
[1, 2, 3].sum() // 6
[1, 2, 3].max() // 3
inject (аналог reduce)
[1, 2, 3].inject(0) { acc, val -> acc + val } // 6
flatten
Разворачивает вложенные коллекции:
[[1, 2], [3, 4]].flatten() // [1, 2, 3, 4]
unique
Удаляет дубликаты:
[1, 2, 2, 3].unique() // [1, 2, 3]
sort
Сортировка:
[3, 1, 2].sort() // [1, 2, 3]
people.sort { it.age }
reverse
Инверсия порядка.
pop, push, shift, unshift
Для работы как со стеком или очередью:
def stack = [1, 2, 3]
stack.push(4) // [1, 2, 3, 4]
stack.pop() // 4
Примечание:
push/popработают с концом списка,shift/unshift— с началом.
Методы для строк
toInteger(), toDouble(), toBoolean()
Безопасное преобразование:
'123'.toInteger() // 123
'false'.toBoolean() // false
padLeft(), padRight()
'5'.padLeft(3, '0') // '005'
tokenize()
Разделение без регулярных выражений:
'a,b,c'.tokenize(',') // ['a', 'b', 'c']
eachMatch(regex)
Итерация по совпадениям:
'abc123def456'.eachMatch(/\d+/) { match -> println match[0] }
// 123
// 456
contains(), startsWith(), endsWith() — уже есть в Java, но Groovy делает их null-safe.
Методы для файлов и потоков
eachLine
new File('Данные.txt').eachLine { line -> println line }
splitEachLine
file.splitEachLine(/\t/) { parts -> println parts[0] }
withReader, withWriter, withInputStream, withOutputStream
Автоматическое закрытие ресурсов:
file.withReader { reader -> ... }
getText(), write(text), append(text)
def content = file.getText('UTF-8')
file.write('Hello', 'UTF-8')
eachFile, eachDir, traverse
Рекурсивный обход:
dir.traverse { file -> if (file.name.endsWith('.groovy')) println file }
deleteDir()
Рекурсивное удаление каталога.
Методы для чисел
times
5.times { println 'Hello' }
upto, downto
1.upto(3) { println it } // 1, 2, 3
5.downto(3) { println it } // 5, 4, 3
step
0.step(10, 2) { println it } // 0, 2, 4, 6, 8
Методы для карт (Map)
get(key, defaultValue)
map.get('name', 'Unknown')
subMap(keys)
map.subMap(['name', 'age'])
collectEntries
Преобразование в новую карту:
[1, 2, 3].collectEntries { [it, it * it] } // [1:1, 2:4, 3:9]
each, eachWithIndex
map.each { key, value -> println "$key = $value" }
25. Регулярные выражения
Groovy упрощает работу с регулярками.
Создание
- Используйте slashy strings (
/.../) — не нужно экранировать\:def pattern = /\d{3}-\d{2}-\d{4}/
Сопоставление
- Оператор
==~— полное совпадение:'123-45-6789' ==~ /\d{3}-\d{2}-\d{4}/ // true - Оператор
=~— частичное совпадение, возвращаетjava.util.regex.Matcher:def matcher = 'ID: 123' =~ /(\d+)/if (matcher) {println matcher[0][1] // '123'}
Замена
'Price: $100'.replaceFirst(/\$(\d+)/) { all, amount -> "€${amount}" }
// Price: €100
Группы
def m = 'John Doe' =~ /(\w+) (\w+)/
if (m) {
def (full, first, last) = m[0]
println "First: $first, Last: $last"
}
26. Многопоточность и параллелизм
GPars (Groovy Parallel Systems)
Хотя GPars больше не активно развивается, его идеи повлияли на современные подходы. В Groovy 4+ рекомендуется использовать Java concurrency utilities, но с Groovy-синтаксисом.
Пример с ExecutorService
def service = Executors.newFixedThreadPool(4)
def futures = (1..10).collect {
service.submit { it * it }
}
futures*.get().each { println it }
service.shutdown()
Параллельная обработка коллекций
def results = [1, 2, 3, 4].parallelStream().map { it * 2 }.toList()
Groovy не добавляет собственных примитивов для async/await, но легко интегрируется с CompletableFuture:
def future = CompletableFuture.supplyAsync { 42 }
future.thenAccept { println it }.join()
27. Управление ресурсами и замыкания
Groovy поощряет использование замыканий для управления жизненным циклом:
new File('input.txt').withReader { reader ->
new File('output.txt').withWriter { writer ->
reader.eachLine { line ->
writer.println line.toUpperCase()
}
}
}
Аналогично для:
- Баз данных (
Sql.withInstance) - HTTP-соединений
- ZIP-архивов
- Сокетов
Это гарантирует вызов close(), даже при исключении.
28. Практические паттерны использования
1. Конфигурационные файлы
config.groovy:
server {
port = 8080
ssl = true
hosts = ['localhost', '127.0.0.1']
}
Загрузка:
def config = new ConfigSlurper().parse(new File('config.groovy').toURL())
println config.server.port
2. ETL-скрипты
new File('input.csv').splitEachLine(',') { fields ->
def record = [id: fields[0], name: fields[1]]
if (record.name) db.insert(record)
}
3. Генерация кода
def template = '''
class ${className} {
${fields.collect { "String $it" }.join('\n ')}
}
'''
def engine = new SimpleTemplateEngine()
println engine.createTemplate(template).make(className: 'User', fields: ['name', 'email'])
4. Административные скрипты
- Очистка логов
- Архивирование
- Мониторинг
5. Jenkins Shared Libraries
DSL на Groovy для стандартизации CI/CD.
29. Инструменты и экосистема
| Инструмент | Назначение |
|---|---|
| Groovy Console | Интерактивная среда выполнения |
| GroovyShell | REPL для экспериментов |
| Gradle | Сборка и управление зависимостями |
| Spock | Тестирование |
| Geb | UI-тестирование (Selenium + jQuery-подобный синтаксис) |
| Ratpack | Лёгкий фреймворк для веб-API |
| Grails | Full-stack веб-фреймворк (на базе Spring Boot) |
30. Советы по стилю и читаемости
- Используйте
defтолько когда тип не важен или выводится. - Предпочитайте
@CompileStaticв производственном коде. - Избегайте глобального метапрограммирования в больших проектах.
- Используйте
ConfigSlurperвместо Properties. - Пишите DSL с
Closure.DELEGATE_FIRST. - Для скриптов — минимум зависимостей, максимум автономности.
31. Структура типичного Groovy-проекта
Groovy не навязывает жёсткой структуры, но следует общепринятым соглашениям JVM-экосистемы, особенно если используется Gradle или Maven.
Минимальная структура (скриптовый проект)
my-groovy-project/
├── scripts/
│ ├── deploy.groovy
│ └── backup.groovy
├── lib/
│ └── helpers.groovy
├── config/
│ └── app.groovy
└── README.md
Стандартная структура (Gradle-проект)
src/
├── main/
│ ├── groovy/ # основной код
│ └── resources/ # конфиги, шаблоны, данные
└── test/
├── groovy/ # тесты (Spock, JUnit)
└── resources/ # тестовые ресурсы
build.gradle
gradle.properties
settings.gradle
Модульный проект (несколько подпроектов)
project-root/
├── core/ # ядро: DSL, утилиты
├── cli/ # командная оболочка
├── web/ # веб-интерфейс (Ratpack/Grails)
├── scripts/ # автономные скрипты
└── build.gradle # корневой билд-файл
Важно: Groovy-файлы могут содержать как классы, так и свободные выражения (скрипты). Файл с
classкомпилируется в.class, файл без — в наследникаgroovy.lang.Script.
32. Организация кода
Классы vs Скрипты
- Классы — для переиспользуемой логики, библиотек, компонентов.
- Скрипты — для автоматизации, одноразовых задач, точек входа.
Пример скрипта (hello.groovy):
println "Hello from script!"
def name = args[0] ?: 'World'
println "Hi, $name!"
Запуск:
groovy hello.groovy Alice
Пакеты и импорты
- Используются так же, как в Java.
- Groovy позволяет опускать
packageв скриптах, но рекомендуется указывать в библиотеках.
Разделение ответственности
- DSL-слои — декларативное описание.
- Интерпретаторы — преобразование DSL в действия.
- Инфраструктурные утилиты — работа с файлами, сетью, БД.
33. Управление зависимостями
Через Gradle
dependencies {
implementation 'org.codehaus.groovy:groovy-all:4.0.15'
implementation 'org.apache.commons:commons-text:1.10.0'
testImplementation 'org.spockframework:spock-core:2.3-groovy-4.0'
}
Через @Grab (в скриптах)
@Grab('org.apache.commons:commons-text:1.10.0')
import org.apache.commons.text.WordUtils
println WordUtils.capitalize('hello world')
Предупреждение:
@Grabиспользует Ivy под капотом, может быть медленным и ненадёжным в изолированных средах. В продакшене предпочтительнее Gradle/Maven.
34. Конфигурация приложения
ConfigSlurper
Читает .groovy-файлы как конфигурацию:
// config/app.groovy
environments {
Разработка {
db.url = 'jdbc:h2:mem:dev'
}
production {
db.url = 'jdbc:postgresql://prod/db'
}
}
Загрузка:
def env = System.getenv('ENV') ?: 'Разработка'
def config = new ConfigSlurper(env).parse(new File('config/app.groovy').toURL())
println config.db.url
Поддержка иерархии
- Возможны вложенные блоки.
- Поддержка
includeчерезConfigObject.merge().
Альтернативы
- JSON/YAML через
JsonSlurper/YamlSlurper(из SnakeYAML). - Properties — через
Properties.
35. Настройка компилятора Groovy
Параметры компиляции (через CLI)
groovyc -j -indy -targetBytecode 17 src/*.groovy
Флаги:
-j— совместная компиляция Java + Groovy-indy— использоватьinvokedynamic-targetBytecode— версия JVM-encoding UTF-8
Через Gradle
compileGroovy {
groovyOptions.optimizationOptions.indy = true
groovyOptions.encoding = 'UTF-8'
groovyOptions.targetBytecode = '17'
}
Custom Compilation Configuration
Можно создать groovyCompiler.groovy:
withConfig(configuration) {
ast(groovy.transform.CompileStatic)
}
И подключить:
compileGroovy {
groovyOptions.configurationScript = file('groovyCompiler.groovy')
}
36. Обработка ошибок и логирование
Исключения
- Используются стандартные Java-механизмы.
- Groovy не требует объявления
throws.
Логирование
Рекомендуется SLF4J:
@Grab('org.slf4j:slf4j-simple:2.0.7')
import org.slf4j.LoggerFactory
def log = LoggerFactory.getLogger(this.class)
log.info("Processing item")
Или встроенное логирование через java.util.logging:
def logger = java.util.logging.Logger.getLogger('MyApp')
logger.info('Started')
37. Тестирование и проверка качества
Spock — основной выбор
- Человекочитаемые спецификации.
- Встроенные моки.
- Параметризованные тесты.
Покрытие кода
- JaCoCo через Gradle:
plugins { id 'jacoco' }jacocoTestReport {reports {html.required = truexml.required = false}}
Статический анализ
- CodeNarc — линтер для Groovy:
plugins { id 'codenarc' }codenarcMain {configFile = file('config/codenarc.groovy')}
Пример codenarc.groovy:
ruleset {
ruleset('rulesets/basic.xml')
ruleset('rulesets/braces.xml')
ruleset('rulesets/naming.xml')
}
38. Запуск и развёртывание
Самодостаточный JAR (fat jar)
jar {
manifest {
attributes 'Main-Class': 'MyApp'
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}
Скрипты как исполняемые файлы (Unix)
#!/usr/bin/env groovy
println "Running as script"
Убедитесь, что
groovyв PATH.
Docker-образ
FROM openjdk:17-jdk-slim
COPY build/libs/app.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
39. Безопасность при выполнении скриптов
Если вы выполняете внешние Groovy-скрипты (например, от пользователей), обязательно ограничьте окружение:
SecureASTCustomizer
def secure = new SecureASTCustomizer()
secure.closuresAllowed = false
secure.methodDefinitionAllowed = false
secure.importsWhitelist = ['java.lang.String']
secure.starImportsWhitelist = []
secure.staticImportsWhitelist = []
secure.tokensBlacklist = [TokenConstants.ASSIGN, TokenConstants.PLUS_PLUS]
def compiler = new CompilerConfiguration()
compiler.addCompilationCustomizers(secure)
def shell = new GroovyShell(this.class.classLoader, new Binding(), compiler)
shell.evaluate(untrustedCode)
Ограничение доступа к файловой системе, сети, рефлексии.
40. Профилирование и отладка
Отладка в IDE
- IntelliJ IDEA и Eclipse имеют отличную поддержку Groovy.
- Точки останова работают в динамическом и статическом режимах.
Логирование состояния
- Используйте
dump()для быстрого инспектирования объекта:println person.dump()
Мониторинг производительности
- VisualVM показывает вызовы Groovy-методов как обычные JVM-методы.
- При использовании
indy— убедитесь, что JIT работает эффективно.
41. Обновление и миграция
Groovy 2 → 3 → 4
Основные изменения:
- Groovy 3: новые операторы (
!in,!instanceof), поддержка Java 13+ синтаксиса. - Groovy 4: Jakarta EE вместо javax, улучшенная поддержка модулей, JDK 17+.
Проверка совместимости
- Запустите тесты с новой версией.
- Используйте
@CompileStaticдля выявления скрытых ошибок.
42. Когда использовать Groovy — и когда нет
Использовать Groovy, если:
- Нужен выразительный DSL.
- Требуется быстрая автоматизация.
- Интеграция с существующим Java-кодом.
- Пишутся тесты (Spock).
- Создаётся конфигурационная система.
Рассмотреть альтернативы (Kotlin, Java), если:
- Производительность критична на каждом этапе.
- Команда не знакома с динамическими языками.
- Требуется строгая типизация на этапе компиляции.
- Проект масштабируется до сотен тысяч строк.
См. также
Другие статьи этого же раздела в боковом меню (как на странице «О разделе»). История Groovy — это кейс эволюции технологии в условиях доминирующей платформы. Из неё можно извлечь несколько обобщаемых принципов. Фундамент для начинающего программиста - что повторить, как работать, чего ожидать. Набор советов, правил, принципов и обычаев в разработке на этом языке. Макросы на уровне языка (начиная с Groovy 2.5) — groovy.transform.Macro позволяет инжектить код, основываясь на анализе AST. Типизация, набор правил определения типа данных значений языка. Арифметические операторы в Groovy предназначены для выполнения математических операций над числами. К ним относятся — + — сложение. Применяется к числам, а также к строкам, где он выполняет… В языке Groovy циклы реализованы как через классические управляющие конструкции, унаследованные от Java и других императивных языков, так и через более выразительные, декларативные подходы,… В этом примере greet — это переменная, содержащая замыкание. Замыкание принимает один параметр name и выводит приветствие. Вызов greet(Groovy) выполняет код внутри замыкания. Нет проверяемых исключений — компилятор Groovy игнорирует механизм throws, принятый в Java. Groovy позволяет работать с переменными без явного указания типа (def), что делает его гибким для скриптов. Кавычки, точки, запятые, скобки и прочие знаки препинания. Groovy использует все ключевые слова Java и добавляет собственные для упрощения синтаксиса. Справочник разделён на логические группы для удобства использования.История языка Groovy
Что требуется знать перед началом изучения языка программирования Groovy
Рекомендации по разработке на Groovy
Основы языка Groovy
Типы данных и объявление переменных
Операторы и выражения в Groovy
Циклы и управляющие конструкции
Объектно-ориентированное программирование в Groovy
Иерархия исключений в Groovy
Особенности и расширения языка Groovy
Синтаксис и пунктуация в Groovy
Ключевые слова языка Groovy